home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Documentation / Tech Notes & Articles / Recipes / Patching OpenDoc < prev    next >
Encoding:
Text File  |  1995-11-07  |  7.9 KB  |  139 lines  |  [TEXT/ttxt]

  1. OpenDoc™ Recipes
  2.  
  3.  
  4. Patching OpenDoc
  5. By The OpenDoc Design Team
  6. April 20th, 1995
  7.  
  8.  
  9. © 1993-1995  Apple Computer, Inc. All Rights Reserved.
  10. Apple, the Apple logo, and Macintosh are registered trademarks of Apple Computer, Inc.
  11. Mac and OpenDoc are trademarks of Apple Computer, Inc. 
  12.  
  13.  
  14.  
  15.  
  16. Introduction
  17.  
  18. OpenDoc is a modular component software architecture.  It is possible to slightly alter, or altogether replace the implementation of OpenDoc's classes.  This document describes how to do that along with details on when it is and is not appropriate to do so.
  19.  
  20. Related Recipes
  21.  
  22. You will probably also want to take a look at the ShellPlugIn Recipe document.
  23. Note that the Patching OpenDoc recipe document only explains how to patch the Session level objects in OpenDoc.
  24. There are other ways OpenDoc can be extended, but these are not typically considered patches.  For other ways of extending OpenDoc, please see Recipes on the following: dispatch modules, focus modules, and container suites.
  25.  
  26. What Can I Patch?
  27.  
  28. All of the Session level objects can be patched.  Here is a list for your convenience:
  29. Arbitrator
  30. Binding
  31. Clipboard
  32. Dispatcher
  33. DragAndDrop
  34. Info
  35. LinkManager
  36. MessageInterface
  37. NameSpaceManager
  38. ShellSemtInterface
  39. StorageSystem
  40. Translation
  41. Undo
  42. WindowState
  43.  
  44. The Bare Necessities
  45.  
  46. To patch OpenDoc, you need three things:
  47. 1. A way to have your patch installer executed
  48. 2. A way to get the current object which you intend to patch
  49. 3. A way to install your object as the object for OpenDoc to use.
  50.  
  51. 1. Having Your Patch Installer Executed
  52.  
  53. There are two different places where you can patch OpenDoc:
  54.  
  55. OpenDoc executes the OpenDoc ShellPlugIns which are installed on a system whenever a user opens a document or a stationery pad, immediately before the root part is opened into a window.  For information on how to write a ShellPlugIn please see the ShellPlugIn Recipe document.  By writing a ShellPlugIn, you may install your patch in your ShellPlugIn's Install method.
  56.  
  57. The second place where you can install your patch is in your part editor's Open method.
  58. Your part editor may install OpenDoc patches ONLY IF your part happens to be the root part of the document.
  59.  
  60. Typically only one of these two places will make sense for a particular patch.  If the patch is universal, independent of what kind of document the user is working with, or perhaps applicable to many kinds of documents, then the ShellPlugIn mechanism is appropriate.  If the patch is very specific, in fact specific only to your part editor, then it is recommended that you install your patch in your part editor's Open method when your part is the root part of the document.
  61.  
  62. Your patch installer  should make sure that the version of the class currently installed for which it is installing a patch for is the same one that your patch was compiled against.  This is necessary due to the fact that the patch class depends on private IDL of the class being patched which may have changed from one version to the next.  If the versions do not precisely match then do not install your patch class.
  63.  
  64. 2. Getting the 'Old' Object
  65.  
  66. To get the old object, call the GetClassName method of Session where ClassName is the name of the class (from the above list) which you are patching.
  67.  
  68. 3. Setting your Object as the object to use
  69.  
  70. To set your object as the object to use, call the SetClassName method of Session where ClassName is the name of the class (sans the OD prefix) which you are patching, and pass in your object.
  71.  
  72. Form of a Patch
  73.  
  74. Let's say you wanted to patch the DragAndDrop object to behave a little differently.  You don't want to reimplement the entire DragAndDrop class, so your DragAndDrop object should delegate to the current DragAndDrop object in order to both minimize your implementation work and ensure that the functionality already in place continues to function.  
  75.  
  76. In order to support the public API of ODDragAndDrop, your DragAndDrop class should be subclass of ODDragAndDrop; optimally your DragAndDrop class would be only be a subtype of ODDragAndDrop, but SOM, like C++, does not make a distinction between subclasses and subtypes.  You should override EVERY method, since your DragAndDrop class is a subtype, not a subclass.  Let me emphasize this because it needs to be explicitly pointed out: you must subclass the private idl of the class, and override ALL methods.  Other than your somInit and somUninit methods, you should NOT call your inherited methods; again, because your class is a subtype.
  77.  
  78. In your InitDragAndDrop method your object should get the old DragAndDrop object by calling the Session'sGetDragAndDrop method and store it in a field; fOldDragAndDrop.  At the end of your InitDragAndDrop method your object should set the Session's DragAndDrop object to be somSelf.
  79.  
  80. In your somUninit method, you should delete the old DragAndDrop object, before calling parent's somUninit method. Be sure that your somUninit method can handle the cases where any/all of your fields are NULL. 
  81.  
  82. All methods of your DragAndDrop class should delegate to the fOldDragAndDrop object after performing their custom functionality, except for the following methods: somInit, somUninit, and InitDragAndDrop.
  83.  
  84. When you create your DragAndDrop class, immediately after creating it with new, you should initialize it by calling its InitDragAndDrop method.
  85.  
  86. Note that the old DragAndDrop object also registers callbacks with the Macintosh DragAndDrop manager, so your class will also have to "patch" those entrypoints into the old DragAndDrop object.  In general, your patch object will have to "patch" all the entrypoints into the previous object; in most cases this only requires the SetClassName call, in some, like DragAndDrop, you need to do more.
  87.  
  88. And that's it. Everything that was said above regarding DragAndDrop pretty much applies to all the rest of the patchable classes listed above.  A simple search and replace would serve to demonstrate how to write a patch for any of the other classes.  Before patching one of the session level objects, be sure to read and thoroughly understand the description of the class in the OpenDoc Class Reference, to make sure that you implement the semantics of your patch correctly.
  89.  
  90. Execution of potential patch installers
  91.  
  92. Whenever any OpenDoc document is opened, after the OpenDoc has received the 'odoc' event and is handling it, it does the following:
  93. • Get the appropriate draft, document and container out of the file passed in the 'odoc' event.
  94. • Install all the Shell Plug-ins.
  95. • Open the root part.
  96.  
  97. As a result, it is possible (just like traditional Macintosh Extensions) to have patches which conflict due to the execution order of the Shell Plug-ins.  However, the root part of the document gets the last say as to which object is patched and how.
  98.  
  99. Caveats
  100.  
  101. • If your patch depends on private headers then your patch may break with a future release of OpenDoc.  As a result, it is highly recommended that your patch installer check the version of OpenDoc which is running before installing your patch.
  102. • If you have to patch to workaround a problem in OpenDoc, PLEASE report the problem the OpenDoc so that we may fix it in a future release (opendoc@applelink.apple.com).
  103. • This code does not contain proper error checking
  104. • This code shows only the bare minimum (i.e. the stuff every patch has).
  105.  
  106. Sample Code
  107.  
  108.  
  109. // Installation code snippet.  Probably called from MyShellPlugIn::Install. -tç
  110.  
  111. InstallDragAndDropPatch(Environment* ev, ODSession* session)
  112. {
  113.     MyDragAndDrop* myDragDrop = new MyDragAndDrop.
  114.  myDragDrop->InitDragAndDrop(ev, session);
  115. }
  116.  
  117.  
  118. // Patch code snippet from MyDragAndDrop.cpp:
  119.  
  120. #include "ODSessn.xh"
  121. #include "DragDrp.xh"
  122. SOM_Scope void  SOMLINK MyDragAndDropInitDragAndDrop(MyDragAndDrop* somSelf, Environment* ev, ODSession* session)
  123. {
  124.  fOldDragAndDrop = session->GetDragAndDrop(ev);
  125.  // Do the rest of my init stuff here
  126.  session->SetDragAndDrop(ev, somSelf);
  127. }
  128.  
  129. SOM_Scope void  SOMLINK MyDragAndDropsomUninit(MyDragAndDrop* somSelf)
  130. {
  131.   delete fOldDragAndDrop;
  132.   parent_somUninit(somSelf);
  133. }
  134.  
  135.  
  136.